package com.bt.springboot.common.util;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 钉钉
 * @author zkx
 * @Date 2022/4/8 11:20
 */
@Slf4j
public class DingTalkUtil extends UnsynchronizedAppenderBase<ILoggingEvent> {

	private final String WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7c3068d2da7c0e21ab26dab700aa96e6367301ec2df4afd32138cd0615a4258f";

	/**
	 * error日志钉钉告警
	 *
	 * 1.配置钉钉群机器人
	 * 2.继承UnsynchronizedAppenderBase<ILoggingEvent> 重写append方法
	 * 3.在logback配置文件加一个append
	 * @param eventObject
	 */
	@Override
	protected void append(ILoggingEvent eventObject) {
//		this.errAlarm(eventObject);
	}

	/**
	 * 错误及异常报警
	 * @param eventObject
	 */
	public void errAlarm(ILoggingEvent eventObject) {

		MarkDown markDown = new MarkDown();
		markDown.setTitle("系统异常");
		markDown.setText(this.genErrAlarmMsg(eventObject));

		DingMsgBody dingMsgBody = new DingMsgBody();
		dingMsgBody.setMsgtype("markdown");
		dingMsgBody.setMarkdown(markDown);
		String result = HttpUtil.post(WEBHOOK, JSONUtil.toJsonStr(dingMsgBody));
		log.info("dingTalkResult=[{}]",result);
	}

	private String genErrAlarmMsg(ILoggingEvent event){
		// error信息
		String formattedMessage = event.getFormattedMessage();
		String loggerName = event.getLoggerName();

		IThrowableProxy iThrowableProxy = event.getThrowableProxy();
		StringBuilder sb = new StringBuilder();
		sb.append("**<font color=#FF0000> 系统异常 </font>**\n\n" +
				"> **loggerName:** " + loggerName + "\n\n" +
				"> **formattedMessage:** " + formattedMessage  + "\n\n");

		// 打印堆栈信息
		if (iThrowableProxy instanceof ThrowableProxy) {
			ThrowableProxy throwableProxy = (ThrowableProxy) iThrowableProxy;
			Throwable throwable = throwableProxy.getThrowable();
			String throwableMsg = throwable.getMessage();
			StackTraceElementProxy[] stackTraceElementProxy = iThrowableProxy.getStackTraceElementProxyArray();

			sb.append(event.getMessage()).append("\n");
			if (StrUtil.isNotEmpty(throwableMsg)) {
				sb.append(throwableMsg).append("\n");
			}
			int i = 0;
			for (StackTraceElementProxy proxy : stackTraceElementProxy) {
				//只打印n行的堆栈
				if (i < 5) {
					sb.append(proxy.getSTEAsString()).append("\n");
				} else {
					break;
				}
				i++;
			}
		} else {
			sb.append(event.getMessage());
		}
		return sb.toString();
	}

	@Data
	private class DingMsgBody {
		private String msgtype;
		private MarkDown markdown;
		private At at;
	}

	@Data
	private class MarkDown {
		private String text;
		private String title;
	}

	@Data
	private class At {
		private String content;
		private List<String> atMobiles;
		private Boolean isAtAll;
	}
}
